<?php

namespace Jinxing\Admin\Http\Controllers;

use Illuminate\Support\Str;
use Jinxing\Admin\Exception;
use Jinxing\Admin\Traits\JsonTrait;
use Littlebug\Repository\Repository;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Jinxing\Admin\Http\Requests\Admin\Common\DeleteAllRequest;
use Jinxing\Admin\Http\Requests\Admin\Common\UploadImageRequest;
use Jinxing\Admin\Http\Requests\Admin\Common\DeleteImageRequest;

/**
 * Class Controller 后台基础控制器
 *
 * @package App\Http\Controllers\Admin
 */
class Controller extends BaseController
{
    /**
     * 引入json 处理
     */
    use JsonTrait, AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    /**
     * @var array 搜索查询的字段
     */
    protected $fields = [];

    /**
     * @var Repository
     */
    protected $repository;

    /**
     * @var string 文件地址
     */
    protected $dirname = 'public';

    /**
     * 获取查询的 model
     *
     * @param array|mixed $condition 查询条件
     *
     * @param array       $fields    查询的字段信息
     *
     * @return \Illuminate\Database\Eloquent\Model|Builder
     */
    public function findModel($condition, $fields = ['*'])
    {
        $fields = empty($this->fields) ? $fields : $this->fields;
        return $this->repository->newBuilder($condition, $fields);
    }

    /**
     * 数据搜索处理
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function search()
    {
        // 处理请求参数
        $offset    = (int)request()->input('offset', 0);
        $limit     = (int)request()->input('limit', 10);
        $draw      = (int)request()->input('draw', 1);
        $condition = request()->input('filters', []);

        // 查询数据
        $query = $this->findModel(array_merge($condition, ['order' => request()->input('orderBy')]), ['*']);
        $total = $query->count();

        // 返回结果
        return $this->json([
            'draw'            => $draw,
            'recordsTotal'    => $total,
            'recordsFiltered' => $total,
            'data'            => $query->offset($offset)->limit($limit)->get(),
        ]);
    }

    /**
     * 图片上传处理
     *
     * @param UploadImageRequest $request
     *
     * @return \Illuminate\Http\JsonResponse
     *
     * @throws Exception
     */
    public function uploadImage(UploadImageRequest $request)
    {
        return $this->success($this->handleVueUpload($request));
    }


    /**
     * 删除全部
     *
     * @param DeleteAllRequest $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function deleteAll(DeleteAllRequest $request)
    {
        // 处理数据
        $ids = explode(',', $request->input('id', ''));
        if (empty($ids)) {
            return $this->systemError('请求参数存在问题');
        }

        return $this->success($this->repository->delete($ids));
    }

    /**
     * 删除图片
     *
     * @param DeleteImageRequest $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function deleteImage(DeleteImageRequest $request)
    {
        $url    = $request->input('url');
        $delete = Str::startsWith($url, '/storage/') ?
            Storage::delete(Str::replaceFirst('/storage/', 'public/', $url)) : false;
        return $this->success([
            'url'    => $request->input('url'),
            'delete' => $delete,
        ]);
    }

    /**
     * vue 文件上传
     *
     * @param FormRequest $request 请求对象
     * @param string|null $name    文件字段名称
     * @param string|null $dirname 文件路径
     *
     * @return array
     * @throws Exception
     */
    protected function handleVueUpload($request, $name = null, $dirname = null)
    {
        $file = $request->file($name ?: 'image');
        if (!$file->isValid()) {
            throw new Exception('上传文件失败', 1001);
        }

        // 上传文件
        if (!$url = $file->store(trim($dirname ?: $this->dirname, '/') . '/' . date('Ymd'))) {
            throw new Exception('上传文件保存失败', 1004);
        }

        return [
            'name' => $file->getClientOriginalName(),
            'url'  => Storage::url($url),
            'path' => $url,
        ];
    }
}
